package com.devunion.bogdan.model.project;

import com.devunion.bogdan.model.event.OntologyPropertyListener;
import com.devunion.bogdan.model.event.OntologyPropertyEvent;

import javax.persistence.*;
import javax.persistence.Entity;
import javax.persistence.CascadeType;
import javax.swing.event.EventListenerList;
import java.util.List;
import java.util.Collections;
import java.util.ArrayList;

import org.hibernate.annotations.*;

/**
 * @author Viktar Liaskovich (devunion@gmail.com)
 */
@Entity
public class Ontology {
    @Id
    @GeneratedValue
    @Column(name = "ontologyId")
    private long ontologyId;

    @Column(name = "text")
    private String text;


//    @Column(name="entries")
//    @OneToMany(fetch = FetchType.EAGER, cascade=CascadeType.ALL)
//    @GenericGenerator(name="uuid-gen", strategy = "uuid")
//    @CollectionId(columns = @Column(name = "COL_ID"), type = @Type(type = "string"), generator = "uuid-gen")
//    @JoinColumn (name = "ontologyPropertyId")
//    @IndexColumn(name="IND_COL")
//    @Cascade({org.hibernate.annotations.CascadeType.ALL})

    @OneToMany(cascade = CascadeType.ALL)
    @Cascade({org.hibernate.annotations.CascadeType.ALL})
    @LazyCollection(LazyCollectionOption.FALSE)
    @IndexColumn(name = "IND_COL")
    private List<OntologyProperty> properties = new ArrayList<OntologyProperty>();

    protected transient EventListenerList listenerList = new EventListenerList();

    public long getOntologyId() {
        return ontologyId;
    }

    public void setOntologyId(long ontologyId) {
        this.ontologyId = ontologyId;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public List<OntologyProperty> getOntologyProperties() {
        return Collections.unmodifiableList(properties);
    }

    public void addOntologyPoperty(OntologyProperty property) {
        if (property == null) {
            throw new IllegalArgumentException("OntologyProperty can't be null");
        }

        properties.add(property);

        fireOntologyPopertyAddedEvent(new OntologyPropertyEvent(this, property));
    }

//    public void addOntologyPoperties(List<OntologyProperty> properties) {
//        if (properties == null) {
//            throw new IllegalArgumentException("OntologyProperty can't be null");
//        }
//
//        for (OntologyProperty p : properties) {
//            this.properties.add(p);
//
//            fireOntologyPopertyAddedEvent(new OntologyPropertyEvent(this, p));
//        }
//    }

    public void removeOntology(OntologyProperty property) {
        if (property == null) {
            throw new IllegalArgumentException("OntologyProperty can't be null");
        }

        this.properties.remove(property);
        fireOntologyPopertyRemovedEvent(new OntologyPropertyEvent(this, property));
    }

//    public void removeOntologyProperties() {
//        if (properties != null) {
//            for (int i =  properties.size()-1; i >= 0; i--) {
//                OntologyProperty p = properties.remove(i);
//                fireOntologyPopertyRemovedEvent(new OntologyPropertyEvent(this, p));
//            }
//        }
//    }

    void fireOntologyPopertyAddedEvent(OntologyPropertyEvent e) {
        // Guaranteed to return a non-null array
        Object[] listeners = listenerList.getListenerList();

        // Process the listeners last to first, notifying
        // those that are interested in this event
        for (int i = listeners.length - 1; i >= 0; i--) {
            if (listeners[i] == OntologyPropertyListener.class) {
                ((OntologyPropertyListener) listeners[i + 1]).propertyAdded(e);
            }
        }
    }

    void fireOntologyPopertyRemovedEvent(OntologyPropertyEvent e) {
        // Guaranteed to return a non-null array
        Object[] listeners = listenerList.getListenerList();

        // Process the listeners last to first, notifying
        // those that are interested in this event
        for (int i = listeners.length - 1; i >= 0; i--) {
            if (listeners[i] == OntologyPropertyListener.class) {
                ((OntologyPropertyListener) listeners[i + 1]).propertyRemoved(e);
            }
        }
    }
}